package com.fengye.common.domain;

import com.fengye.common.constants.AppHttpCodeEnum;

import java.io.Serializable;

/**
 * 接口返回的通用的JSON格式
 * @author sunlei
 * @param <T>
 */
//@JsonInclude(JsonInclude.Include.NON_EMPTY) // 去除JSON数据中值为空的键值对，还可以在配置文件中全局配置，不过影响比较大，谨慎全局配置，spring.jackson.default-property-inclusion: non_null
public class ResponseResult<T> implements Serializable {
    /** 状态码 */
    private Integer code;
    /** 描述信息 */
    private String message;
    /** 响应时间戳 */
    private Long timestamp;
    /** 数据 */
    private T data;

    /*************************** getter、setter *************************/
    public Integer getCode() {
        return code;
    }

    public ResponseResult<T> setCode(Integer code) {
        this.code = code;
        return this;
    }

    public String getMessage() {
        return message;
    }

    public ResponseResult<T> setMessage(String message) {
        this.message = message;
        return this;
    }

    public Long getTimestamp() {
        return timestamp;
    }

    public ResponseResult<T> setTimestamp(Long timestamp) {
        this.timestamp = timestamp;
        return this;
    }

    public T getData() {
        return data;
    }

    public ResponseResult<T> setData(T data) {
        this.data = data;
        return this;
    }

    /*************************** constructor *************************/

    public ResponseResult(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.timestamp = System.currentTimeMillis();
        this.data = data;
    }

    /************************ public static method ********************/
    // 成功
    public static <T> ResponseResult<T> success(Integer code, String message, T data) {
        return ResponseResult.createResult(code, message, data);
    }

    public static <T> ResponseResult<T> success() {
        return ResponseResult.createResult(AppHttpCodeEnum.SUCCESS.getCode(), AppHttpCodeEnum.SUCCESS.getMsg(), null);
    }

    public static <T> ResponseResult<T> success(Integer code) {
        return ResponseResult.createResult(code, AppHttpCodeEnum.SUCCESS.getMsg(), null);
    }

    public static <T> ResponseResult<T> success(String message) {
        return ResponseResult.createResult(AppHttpCodeEnum.SUCCESS.getCode(), message, null);
    }

    public static <T> ResponseResult<T> success(T data) {
        return ResponseResult.createResult(AppHttpCodeEnum.SUCCESS.getCode(), AppHttpCodeEnum.SUCCESS.getMsg(), data);
    }

    public static <T> ResponseResult<T> success(Integer code, String message) {
        return ResponseResult.createResult(code, message, null);
    }

    public static <T> ResponseResult<T> success(Integer code, T data) {
        return ResponseResult.createResult(code, AppHttpCodeEnum.SUCCESS.getMsg(), data);
    }

    public static <T> ResponseResult<T> success(String message, T data) {
        return ResponseResult.createResult(AppHttpCodeEnum.SUCCESS.getCode(), message, data);
    }

    public static <T> ResponseResult<T> success(AppHttpCodeEnum appHttpCodeEnum) {
        return ResponseResult.createResult(appHttpCodeEnum.getCode(), appHttpCodeEnum.getMsg(), null);
    }

    public static <T> ResponseResult<T> success(AppHttpCodeEnum appHttpCodeEnum, T data) {
        return ResponseResult.createResult(appHttpCodeEnum.getCode(), appHttpCodeEnum.getMsg(), data);
    }

    // 失败
    public static <T> ResponseResult<T> fail(Integer code, String message, T data) {
        return ResponseResult.createResult(code, message, data);
    }

    public static <T> ResponseResult<T> fail(Integer code, String message) {
        return ResponseResult.createResult(code, message, null);
    }

    public static <T> ResponseResult<T> fail(AppHttpCodeEnum appHttpCodeEnum) {
        return ResponseResult.createResult(appHttpCodeEnum.getCode(), appHttpCodeEnum.getMsg(), null);
    }

    /**
     * 创建ResponseResult对象
     * @param code 状态码
     * @param message 描述信息
     * @param data 数据
     * @param <T> 数据类型
     * @return ResponseResult对象
     */
    private static final <T> ResponseResult<T> createResult(Integer code, String message, T data) {
        return new ResponseResult<>(code, message, data);
    }
}
